﻿// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Windows.ApplicationModel.Resources.Core;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using System.Net.Http;
using Windows.Data.Json;
using Windows.ApplicationModel;
using Windows.Storage.Streams;
using System.Threading.Tasks;
using Windows.Storage;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization.Json;
using Windows.UI.Xaml.Controls;
using Windows.UI.ApplicationSettings;

// The data model defined by this file serves as a representative example of a strongly-typed
// model that supports notification when members are added, removed, or modified.  The property
// names chosen coincide with data bindings in the standard item templates.
//
// Applications may use this model as a starting point and build on it, or discard it entirely and
// replace it with something appropriate to their needs.

namespace UITTimetable.Data {
    [Windows.Foundation.Metadata.WebHostHidden]
    public abstract class TimetableDataCommon : UITTimetable.Common.BindableBase {
        internal static Uri _baseUri = new Uri("ms-appx:///");

        public TimetableDataCommon(String uniqueId, String title, String shortTitle, String imagePath) {
            this._uniqueId = uniqueId;
            this._title = title;
            this._shortTitle = shortTitle;
            this._imagePath = imagePath;
        }

        private string _uniqueId = string.Empty;
        public string UniqueId {
            get { return this._uniqueId; }
            set { this.SetProperty(ref this._uniqueId, value); }
        }

        private string _title = string.Empty;
        public string Title {
            get { return this._title; }
            set { this.SetProperty(ref this._title, value); }
        }

        private string _icon = string.Empty;
        public string Icon {
            get { return this._icon; }
            set { this.SetProperty(ref this._icon, value); }
        }

        private string _shortTitle = string.Empty;
        public string ShortTitle {
            get { return this._shortTitle; }
            set { this.SetProperty(ref this._shortTitle, value); }
        }

        private ImageSource _image = null;
        private String _imagePath = null;

        public Uri ImagePath {
            get {
                return new Uri(TimetableDataCommon._baseUri, this._imagePath);
            }
        }

        public ImageSource Image {
            get {
                if (this._image == null && this._imagePath != null) {
                    this._image = new BitmapImage(new Uri(TimetableDataCommon._baseUri, this._imagePath));
                }
                return this._image;
            }

            set {
                this._imagePath = null;
                this.SetProperty(ref this._image, value);
            }
        }

        public void SetImage(String path) {
            this._image = null;
            this._imagePath = path;
            this.OnPropertyChanged("Image");
        }

        public string GetImageUri() {
            return _imagePath;
        }
    }

    public class TimetableDataItem : TimetableDataCommon {
        public TimetableDataItem()
            : base(String.Empty, String.Empty, String.Empty, String.Empty) {
        }

        public TimetableDataItem(String uniqueId, String title, String shortTitle, String imagePath, TimetableDataGroup group)
            : base(uniqueId, title, shortTitle, imagePath) {
            this._group = group;
        }

        private CommonDataGroup _group;
        public CommonDataGroup Group {
            get { return this._group; }
            set { this.SetProperty(ref this._group, value); }
        }

        private ImageSource _tileImage;
        private string _tileImagePath;

        public Uri TileImagePath {
            get {
                return new Uri(TimetableDataCommon._baseUri, this._tileImagePath);
            }
        }

        public ImageSource TileImage {
            get {
                if (this._tileImage == null && this._tileImagePath != null) {
                    this._tileImage = new BitmapImage(new Uri(TimetableDataCommon._baseUri, this._tileImagePath));
                }
                return this._tileImage;
            }
            set {
                this._tileImagePath = null;
                this.SetProperty(ref this._tileImage, value);
            }
        }

        public void SetTileImage(String path) {
            this._tileImage = null;
            this._tileImagePath = path;
            this.OnPropertyChanged("TileImage");
        }
    }

    #region Subject Data Item

    public class TimetableSubjectDataItem : TimetableDataItem {
        public TimetableSubjectDataItem(String mamonhoc, String ten, String mamon, String malop, int sotinchi,
            String giangvien, String phong, int ngayhoc, DateTime batdau, DateTime ketthuc, String ghichu)
            : base() {

            this._batdau = batdau;
            this._ghichu = ghichu;
            this._giangvien = giangvien;
            this._ketthuc = ketthuc;
            this._malop = malop;
            this._mamon = mamon;
            this._ngayhoc = ngayhoc;
            this._phong = phong;
            this._sotinchi = sotinchi;
            this._ten = ten;
        }

        public TimetableSubjectDataItem(String uniqueId, String title, String shortTitle, String imagePath, TimetableDataGroup group, String mamonhoc, String ten, String mamon, String malop, int sotinchi,
            String giangvien, String phong, int ngayhoc, DateTime batdau, DateTime ketthuc, String ghichu)
            : base(uniqueId, title, shortTitle, imagePath, group) {

            this._batdau = batdau;
            this._ghichu = ghichu;
            this._giangvien = giangvien;
            this._ketthuc = ketthuc;
            this._malop = malop;
            this._mamon = mamon;
            this._ngayhoc = ngayhoc;
            this._phong = phong;
            this._sotinchi = sotinchi;
            this._ten = ten;
        }

        private string _mamonhoc = string.Empty;
        public string MaMonHoc {
            get { return this._mamonhoc; }
            set { this.SetProperty(ref this._mamonhoc, value); }
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private string _mamon = string.Empty;
        public string MaMon {
            get { return this._mamon; }
            set { this.SetProperty(ref this._mamon, value); }
        }

        private string _malop = string.Empty;
        public string MaLop {
            get { return this._malop; }
            set { this.SetProperty(ref this._malop, value); }
        }

        private int _sotinchi = 0;
        public int SoTinChi {
            get { return this._sotinchi; }
            set { this.SetProperty(ref this._sotinchi, value); }
        }

        private int _ngayhoc = 0;
        public int NgayHoc {
            get { return this._ngayhoc; }
            set { this.SetProperty(ref this._ngayhoc, value); }
        }

        private string _giangvien = string.Empty;
        public string GiangVien {
            get { return this._giangvien; }
            set { this.SetProperty(ref this._giangvien, value); }
        }

        private string _phong = string.Empty;
        public string Phong {
            get { return this._phong; }
            set { this.SetProperty(ref this._phong, value); }
        }

        private DateTime _batdau = DateTime.Now;
        public DateTime BatDau {
            get { return this._batdau; }
            set { this.SetProperty(ref this._batdau, value); }
        }

        private DateTime _ketthuc = DateTime.Now;
        public DateTime KetThuc {
            get { return this._ketthuc; }
            set { this.SetProperty(ref this._ketthuc, value); }
        }

        private string _ghichu = string.Empty;
        public string GhiChu {
            get { return this._ghichu; }
            set { this.SetProperty(ref this._ghichu, value); }
        }

        private string _tonghop = string.Empty;
        public string TongHop {
            get { return this._tonghop; }
            set { this.SetProperty(ref this._tonghop, value); }
        }

    }

    public class CalendarSubjectDataItem : TimetableDataItem {
        public CalendarSubjectDataItem(String mamonhoc, String ten, String mamon, String malop, int sotinchi,
            String giangvien, String phong, int ngayhoc, DateTime batdau, DateTime ketthuc, String ghichu)
            : base() {

            this._batdau = batdau;
            this._ghichu = ghichu;
            this._giangvien = giangvien;
            this._ketthuc = ketthuc;
            this._malop = malop;
            this._mamon = mamon;
            this._ngayhoc = ngayhoc;
            this._phong = phong;
            this._sotinchi = sotinchi;
            this._ten = ten;
        }

        public CalendarSubjectDataItem(String uniqueId, String title, String shortTitle, String imagePath, TimetableDataGroup group, String mamonhoc, String ten, String mamon, String malop, int sotinchi,
            String giangvien, String phong, int ngayhoc, DateTime batdau, DateTime ketthuc, String ghichu)
            : base(uniqueId, title, shortTitle, imagePath, group) {

            this._batdau = batdau;
            this._ghichu = ghichu;
            this._giangvien = giangvien;
            this._ketthuc = ketthuc;
            this._malop = malop;
            this._mamon = mamon;
            this._ngayhoc = ngayhoc;
            this._phong = phong;
            this._sotinchi = sotinchi;
            this._ten = ten;
        }

        private string _mamonhoc = string.Empty;
        public string MaMonHoc {
            get { return this._mamonhoc; }
            set { this.SetProperty(ref this._mamonhoc, value); }
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private string _mamon = string.Empty;
        public string MaMon {
            get { return this._mamon; }
            set { this.SetProperty(ref this._mamon, value); }
        }

        private string _malop = string.Empty;
        public string MaLop {
            get { return this._malop; }
            set { this.SetProperty(ref this._malop, value); }
        }

        private int _sotinchi = 0;
        public int SoTinChi {
            get { return this._sotinchi; }
            set { this.SetProperty(ref this._sotinchi, value); }
        }

        private int _ngayhoc = 0;
        public int NgayHoc {
            get { return this._ngayhoc; }
            set { this.SetProperty(ref this._ngayhoc, value); }
        }

        private string _giangvien = string.Empty;
        public string GiangVien {
            get { return this._giangvien; }
            set { this.SetProperty(ref this._giangvien, value); }
        }

        private string _phong = string.Empty;
        public string Phong {
            get { return this._phong; }
            set { this.SetProperty(ref this._phong, value); }
        }

        private DateTime _batdau = DateTime.Now;
        public DateTime BatDau {
            get { return this._batdau; }
            set { this.SetProperty(ref this._batdau, value); }
        }

        private DateTime _ketthuc = DateTime.Now;
        public DateTime KetThuc {
            get { return this._ketthuc; }
            set { this.SetProperty(ref this._ketthuc, value); }
        }

        private string _ghichu = string.Empty;
        public string GhiChu {
            get { return this._ghichu; }
            set { this.SetProperty(ref this._ghichu, value); }
        }

        private ObservableCollection<CalendarThiDataItem> _allThi = new ObservableCollection<CalendarThiDataItem>();
        public ObservableCollection<CalendarThiDataItem> AllThi {
            get { return this._allThi; }
            set { this.SetProperty(ref this._allThi, value); }
        }

        private ObservableCollection<CalendarBaiTapDataItem> _allBaiTap = new ObservableCollection<CalendarBaiTapDataItem>();
        public ObservableCollection<CalendarBaiTapDataItem> AllBaiTap {
            get { return this._allBaiTap; }
            set { this.SetProperty(ref this._allBaiTap, value); }
        }
    }

    #endregion

    #region Student Data Item

    public class StudentDataItem : TimetableDataItem {
        public StudentDataItem(String mssv, String ten, String lop, String khoa, String hocky, String namhoc)
            : base() {

            this._mssv = mssv;
            this._ten = ten;
            this._lop = lop;
            this._khoa = khoa;
            this._hocky = hocky;
            this._namhoc = namhoc;
        }

        public StudentDataItem(String uniqueId, String title, String shortTitle, String imagePath, TimetableDataGroup group, String mssv, String ten, String lop, String khoa, String hocky, String namhoc)
            : base(uniqueId, title, shortTitle, imagePath, group) {

            this._mssv = mssv;
            this._ten = ten;
            this._lop = lop;
            this._khoa = khoa;
            this._hocky = hocky;
            this._namhoc = namhoc;
        }

        private string _mssv = string.Empty;
        public string MSSV {
            get { return this._mssv; }
            set { this.SetProperty(ref this._mssv, value); }
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private string _lop = string.Empty;
        public string Lop {
            get { return this._lop; }
            set { this.SetProperty(ref this._lop, value); }
        }

        private string _khoa = string.Empty;
        public string Khoa {
            get { return this._khoa; }
            set { this.SetProperty(ref this._khoa, value); }
        }

        private string _namhoc = string.Empty;
        public string NamHoc {
            get { return this._namhoc; }
            set { this.SetProperty(ref this._namhoc, value); }
        }

        private string _hocky = string.Empty;
        public string HocKy {
            get { return this._hocky; }
            set { this.SetProperty(ref this._hocky, value); }
        }
    }

    #endregion

    #region Calendar Extended Item

    public sealed class CalendarThiDataItem : UITTimetable.Common.BindableBase {

        public CalendarThiDataItem(String ten, DateTime ngaygio, String ghichu) {
            this._ghichu = ghichu;
            this._ngaygio = ngaygio;
            this._ten = ten;
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private DateTime _ngaygio = DateTime.Now;
        public DateTime NgayGio {
            get { return this._ngaygio; }
            set { this.SetProperty(ref this._ngaygio, value); }
        }

        private string _ghichu = string.Empty;
        public string GhiChu {
            get { return this._ghichu; }
            set { this.SetProperty(ref this._ghichu, value); }
        }
    }

    public sealed class CalendarBaiTapDataItem : UITTimetable.Common.BindableBase {

        public CalendarBaiTapDataItem(String ten, DateTime ngayhethan, String noidung) {
            this._noidung = noidung;
            this._ngayhethan = ngayhethan;
            this._ten = ten;
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private DateTime _ngayhethan = DateTime.Now;
        public DateTime NgayHetHan {
            get { return this._ngayhethan; }
            set { this.SetProperty(ref this._ngayhethan, value); }
        }

        private string _noidung = string.Empty;
        public string NoiDung {
            get { return this._noidung; }
            set { this.SetProperty(ref this._noidung, value); }
        }
    }

    #endregion

    #region Data Groups

    public class CommonDataGroup : TimetableDataCommon {

        public CommonDataGroup()
            : base(String.Empty, String.Empty, String.Empty, String.Empty) {
        }

        public CommonDataGroup(String uniqueId, String title, String shortTitle, String imagePath)
            : base(uniqueId, title, shortTitle, imagePath) {
        }

        private ObservableCollection<TimetableDataItem> _items = new ObservableCollection<TimetableDataItem>();
        public ObservableCollection<TimetableDataItem> Items {
            get { return this._items; }
        }

        public IEnumerable<TimetableDataItem> TopItems {
            get { return this._items.Take(12); }
        }

        private ImageSource _groupImage;
        private string _groupImagePath;

        public ImageSource GroupImage {
            get {
                if (this._groupImage == null && this._groupImagePath != null) {
                    this._groupImage = new BitmapImage(new Uri(TimetableDataCommon._baseUri, this._groupImagePath));
                }
                return this._groupImage;
            }
            set {
                this._groupImagePath = null;
                this.SetProperty(ref this._groupImage, value);
            }
        }

        public int SubjectCount {
            get {
                return this.Items.Count;
            }
        }

        public void SetGroupImage(String path) {
            this._groupImage = null;
            this._groupImagePath = path;
            this.OnPropertyChanged("GroupImage");
        }

    }

    public class TimetableDataGroup : CommonDataGroup {
        public TimetableDataGroup(String matkb, String ten, DateTime batdau, DateTime ketthuc)
            : base(String.Empty, String.Empty, String.Empty, String.Empty) {

            this._mtkb = matkb;
            this._ten = ten;
            this._batdau = batdau;
            this._ketthuc = ketthuc;
        }

        public TimetableDataGroup(String uniqueId, String title, String shortTitle, String imagePath, String matkb, String ten, DateTime batdau, DateTime ketthuc)
            : base(uniqueId, title, shortTitle, imagePath) {

            this._mtkb = matkb;
            this._ten = ten;
            this._batdau = batdau;
            this._ketthuc = ketthuc;
        }


        private string _mtkb = string.Empty;
        public string MaTKB {
            get { return this._mtkb; }
            set { this.SetProperty(ref this._mtkb, value); }
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private DateTime _batdau = DateTime.Now;
        public DateTime BatDau {
            get { return this._batdau; }
            set { this.SetProperty(ref this._batdau, value); }
        }

        private DateTime _ketthuc = DateTime.Now;
        public DateTime KetThuc {
            get { return this._ketthuc; }
            set { this.SetProperty(ref this._ketthuc, value); }
        }
    }

    public class CalendarDataGroup : CommonDataGroup {

        public CalendarDataGroup(String malich, String ten, int hocky, String namhoc, String ghichu)
            : base(String.Empty, String.Empty, String.Empty, String.Empty) {

            this._malich = malich;
            this._ten = ten;
            this._hocky = hocky;
            this._namhoc = namhoc;
            this._ghichu = ghichu;
        }

        public CalendarDataGroup(String uniqueId, String title, String shortTitle, String imagePath, String malich, String ten, int hocky, String namhoc, String ghichu)
            : base(uniqueId, title, shortTitle, imagePath) {

            this._malich = malich;
            this._ten = ten;
            this._hocky = hocky;
            this._namhoc = namhoc;
            this._ghichu = ghichu;
        }

        private string _malich = string.Empty;
        public string MaLich {
            get { return this._malich; }
            set { this.SetProperty(ref this._malich, value); }
        }

        private string _ten = string.Empty;
        public string Ten {
            get { return this._ten; }
            set { this.SetProperty(ref this._ten, value); }
        }

        private int _hocky = 1;
        public int HocKy {
            get { return this._hocky; }
            set { this.SetProperty(ref this._hocky, value); }
        }

        private string _namhoc = string.Empty;
        public string NamHoc {
            get { return this._namhoc; }
            set { this.SetProperty(ref this._namhoc, value); }
        }

        private string _ghichu = string.Empty;
        public string GhiChu {
            get { return this._ghichu; }
            set { this.SetProperty(ref this._ghichu, value); }
        }
    }

    public class TKBDataGroup : TimetableDataCommon {
        public TKBDataGroup()
            : base(String.Empty, String.Empty, String.Empty, String.Empty) {
        }

        public TKBDataGroup(String uniqueId, String title, String shortTitle, String imagePath)
            : base(uniqueId, title, shortTitle, imagePath) {

        }

        private ObservableCollection<CommonDataGroup> _items = new ObservableCollection<CommonDataGroup>();
        public ObservableCollection<CommonDataGroup> Items {
            get { return this._items; }
        }

        public IEnumerable<CommonDataGroup> TopItems {
            get { return this._items.Take(12); }
        }

        public void PopularizeContent(int type) {
            switch (type) {
                case 0:
                    // Them item sync
                    CommonDataGroup syncTile = new CommonDataGroup("SYNC_TKB", "sync data from web", "daa.uit.edu.vn", String.Empty);
                    syncTile.Icon = "\uE117";
                    _items.Add(syncTile);
                    break;
                case 1:
                    // Them item del
                    CommonDataGroup delTile = new CommonDataGroup("DEL_TKB_LOCAL", "clear cached data to computer", "need to resync", String.Empty);
                    delTile.Icon = "\uE107";
                    _items.Add(delTile);
                    break;
            }

        }
    }

    #endregion

    public sealed class TimetableDataSource : UITTimetable.Common.BindableBase {
        //public event EventHandler RecipesLoaded;

        public static Dictionary<String, String> _tempString = new Dictionary<String, String>();

        public TimetableDataSource() {

        }

        private static TimetableDataSource _timetableDataSource = new TimetableDataSource();

        public static List<String> _roomList = null;

        private ObservableCollection<CommonDataGroup> _allGroups = new ObservableCollection<CommonDataGroup>();
        public ObservableCollection<CommonDataGroup> AllGroups {
            get { return this._allGroups; }
        }

        private ObservableCollection<TimetableDataCommon> _allGroups_Design = new ObservableCollection<TimetableDataCommon>();
        public ObservableCollection<TimetableDataCommon> AllGroups_Design {
            get { return this._allGroups_Design; }
        }

        private StudentDataItem _studentItem = new StudentDataItem(String.Empty, String.Empty, String.Empty, String.Empty, String.Empty, String.Empty);
        public StudentDataItem StudentItem {
            get { return this._studentItem; }
            set { SetProperty(ref this._studentItem, value); }
        }

        public static IEnumerable<CommonDataGroup> GetGroups(string uniqueId) {
            if (!uniqueId.Equals("AllGroups")) throw new ArgumentException("Only 'AllGroups' is supported as a collection of groups");

            return _timetableDataSource.AllGroups;
        }

        public static CommonDataGroup GetGroup(string uniqueId) {
            // Simple linear search is acceptable for small data sets
            var matches = _timetableDataSource.AllGroups.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static TimetableDataItem GetItem(string uniqueId) {
            // Simple linear search is acceptable for small data sets
            var matches = _timetableDataSource.AllGroups.SelectMany(group => group.Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static IEnumerable<TimetableDataCommon> GetGroups_Design(string uniqueId) {
            if (!uniqueId.Equals("AllGroups_Design")) throw new ArgumentException("Only 'AllGroups_Design' is supported as a collection of groups");

            return _timetableDataSource.AllGroups_Design;
        }

        public static TimetableDataCommon GetGroup_Design(string uniqueId) {
            // Simple linear search is acceptable for small data sets
            var matches = _timetableDataSource.AllGroups_Design.Where((group) => group.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static CommonDataGroup GetItem_Design(string uniqueId) {
            // Simple linear search is acceptable for small data sets
            var matches = _timetableDataSource.AllGroups_Design.SelectMany(group => (group as TKBDataGroup).Items).Where((item) => item.UniqueId.Equals(uniqueId));
            if (matches.Count() == 1) return matches.First();
            return null;
        }

        public static async Task LoadRemoteDataAsync() {
            // Retrieve recipe data from Azure
            var client = new HttpClient();
            client.MaxResponseContentBufferSize = 1024 * 1024; // Read up to 1 MB of data
            var response = await client.GetAsync(new Uri("http://contosorecipes8.blob.core.windows.net/AzureRecipesRP"));
            var result = await response.Content.ReadAsStringAsync();

            // Parse the JSON recipe data
            var timetable = JsonArray.Parse(result);

            // Convert the JSON objects into RecipeDataItems and RecipeDataGroups
            CreateTimetableGroup(timetable, _timetableDataSource._allGroups);
        }

        public static async Task LoadLocalDataAsync() {

            var file = await Package.Current.InstalledLocation.GetFileAsync("Data\\timetable.txt");
            var result = await FileIO.ReadTextAsync(file);

            // Parse the JSON recipe data
            var data = JsonArray.Parse(result);

            CreateTimetableGroup(data, _timetableDataSource._allGroups);

            file = await Package.Current.InstalledLocation.GetFileAsync("Data\\lich.txt");
            result = await FileIO.ReadTextAsync(file);

            // Parse the JSON recipe data
            data = JsonArray.Parse(result);

            CreateCalendarGroup(data, _timetableDataSource._allGroups);

            file = await Package.Current.InstalledLocation.GetFileAsync("Data\\sinhvien.txt");
            result = await FileIO.ReadTextAsync(file);

            // Parse the JSON recipe data
            data = JsonArray.Parse(result);

            CreateStudentDataItem(data);
        }

        public static async Task LoadRoom() {
            var file = await Package.Current.InstalledLocation.GetFileAsync("Data\\room.txt");
            var result = await FileIO.ReadTextAsync(file);
            _roomList = result.Split(new char[] { ',' }).ToList<String>();

        }

        public static async Task LoadRemoteTKB(ProgressBar proBar) {

            var temp = (_timetableDataSource._allGroups_Design[0] as TKBDataGroup).Items.Last();
            temp.Title = "syncing...";
            proBar.IsIndeterminate = true;

            (_timetableDataSource._allGroups_Design[0] as TKBDataGroup).Items.Clear();
            (_timetableDataSource._allGroups_Design[0] as TKBDataGroup).Items.Add(temp);

            //var file = await Package.Current.InstalledLocation.GetFileAsync("Data\\timetable.txt");
            //var result = await FileIO.ReadTextAsync(file);

            // Get number of timetable to sync

            var client = new HttpClient();
            client.MaxResponseContentBufferSize = 1024 * 1024; // Read up to 1 MB of data
            var response = await client.GetAsync(new Uri("http://khabeouit.orgfree.com/data_uittimetable/sync.txt"));
            var result = await response.Content.ReadAsStringAsync();

            int count = int.Parse(result);

            for (int i = 0; i < count; i++) {

                // Retrieve recipe data from Azure
                client = new HttpClient();
                client.MaxResponseContentBufferSize = 1024 * 1024; // Read up to 1 MB of data
                response = await client.GetAsync(new Uri("http://khabeouit.orgfree.com/data_uittimetable/timetable" + i.ToString() + ".txt"));
                result = await response.Content.ReadAsStringAsync();

                _tempString.Add("0", result);

                // Parse the JSON recipe data
                var data = JsonArray.Parse(result);

                CreateTKBGroup(data);
            }

            temp.Title = "sync from web";
            proBar.IsIndeterminate = false;

            // Save test
            //SaveTimetable(0);

            //Load test
            //LoadLocalTKB();
        }

        public static async Task LoadLocalTKB() {

            var temp = (_timetableDataSource._allGroups_Design[1] as TKBDataGroup).Items.Last();

            (_timetableDataSource._allGroups_Design[1] as TKBDataGroup).Items.Clear();
            (_timetableDataSource._allGroups_Design[1] as TKBDataGroup).Items.Add(temp);

            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            var files = await folder.GetFilesAsync();

            foreach (StorageFile file in files) {

                var result = await FileIO.ReadTextAsync(file);
                var data = JsonArray.Parse(result);
                CreateTKBSavedGroup(data, file.DateCreated.DateTime);
            }

            await TimetableDataSource.LoadRoom();

        }

        private static void CreateTKBSavedGroup(JsonArray array, DateTime date) {
            var destGroupsList = (_timetableDataSource._allGroups_Design.Where(t => t.UniqueId.Equals("TKB_SAVED")).ElementAt(0) as TKBDataGroup).Items;

            foreach (var ttitem in array) {

                var timetable = ttitem.GetObject();

                var group = new TimetableDataGroup("TKB_SAVED" + Guid.NewGuid().ToString(), String.Empty, DateTime.Now, DateTime.Now);

                foreach (var key in timetable.Keys) {

                    IJsonValue val;

                    var provider = CultureInfo.InvariantCulture;
                    var format = "d/M/yyyy";

                    if (!timetable.TryGetValue(key, out val))
                        continue;

                    switch (key) {
                        case "tenthoikhoabieu":
                            group.Ten = group.Title = val.GetString();
                            group.ShortTitle = "Updated on " + date.ToString("d/M/yyyy hh:mm tt");
                            break;
                        case "batdau":
                            group.BatDau = DateTime.ParseExact(val.GetString(), format, provider);
                            break;
                        case "ketthuc":
                            group.KetThuc = DateTime.ParseExact(val.GetString(), format, provider);
                            break;
                        case "danhsachmonhoc":
                            var monhoc = val.GetArray();
                            format = "h:m tt";
                            foreach (var item in monhoc) {
                                var monhocitem = new TimetableSubjectDataItem(String.Empty, String.Empty, String.Empty, String.Empty, 0, String.Empty, String.Empty, 0, DateTime.Now, DateTime.Now, String.Empty);
                                var obj = item.GetObject();
                                foreach (var k in obj.Keys) {
                                    IJsonValue val1;
                                    if (!obj.TryGetValue(k, out val1))
                                        continue;
                                    switch (k) {
                                        case "mamon":
                                            monhocitem.MaMon = val1.GetString();
                                            break;
                                        case "malop":
                                            monhocitem.MaLop = val1.GetString();
                                            break;
                                        case "ten":
                                            monhocitem.Ten = monhocitem.ShortTitle = val1.GetString();
                                            break;
                                        case "sotinchi":
                                            monhocitem.SoTinChi = (int)val1.GetNumber();
                                            break;
                                        case "giangvien":
                                            monhocitem.GiangVien = val1.GetString();
                                            break;
                                        case "phong":
                                            monhocitem.Phong = val1.GetString();
                                            break;
                                        case "ngayhoc":
                                            monhocitem.NgayHoc = (int)val1.GetNumber();
                                            break;
                                        case "batdau":
                                            monhocitem.BatDau = DateTime.ParseExact(val1.GetString(), format, provider);
                                            break;
                                        case "ketthuc":
                                            monhocitem.KetThuc = DateTime.ParseExact(val1.GetString(), format, provider);
                                            break;
                                        case "ghichu":
                                            monhocitem.GhiChu = val1.GetString();
                                            break;
                                    }
                                }
                                monhocitem.MaMonHoc = monhocitem.Title = monhocitem.MaMon + "." + monhocitem.MaLop;
                                monhocitem.UniqueId = monhocitem.MaMonHoc + "_" + group.MaTKB;
                                monhocitem.Group = group;
                                monhocitem.Icon = "\uE1D3";
                                monhocitem.SetImage("ms-appx:///Assets//uit.png");

                                //Tong hop thong tin mon hoc
                                monhocitem.TongHop = ThuTrongTuan(monhocitem.NgayHoc) + "\n" + "Room: " + monhocitem.Phong + "\n" + "Time: " + monhocitem.BatDau.ToString("hh:mm tt") + " - " + monhocitem.KetThuc.ToString("hh:mm tt");

                                group.Items.Add(monhocitem);
                            }
                            break;
                    }

                }
                group.UniqueId = group.MaTKB;
                group.Icon = "\uE1DC";
                group.SetImage("ms-appx:///Assets//uit.png");
                //_timetableDataSource._allGroups.Add(group);
                destGroupsList.Insert(0, group);
            }
        }

        public static async Task SaveTimetable(String id) {
            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.CreateFolderAsync("data", CreationCollisionOption.OpenIfExists);
            StorageFile file = await folder.CreateFileAsync("timetable" + Guid.NewGuid() + ".txt", CreationCollisionOption.ReplaceExisting);
            using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite)) {
                using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0)) {
                    using (DataWriter dataWriter = new DataWriter(outputStream)) {
                        //TODO: Replace "Bytes" with the type you want to write.
                        dataWriter.WriteString(_tempString.Where(t => t.Key == id).ElementAt(0).Value);
                        await dataWriter.StoreAsync();
                        dataWriter.DetachStream();
                    }

                    await outputStream.FlushAsync();
                }
            }
            await LoadLocalTKB();
        }

        public static async Task DeletaLocalTimetable() {
            StorageFolder folder = ApplicationData.Current.LocalFolder;
            folder = await folder.GetFolderAsync("data");
            var files = await folder.GetFilesAsync();

            foreach (StorageFile file in files) {
                await file.DeleteAsync(StorageDeleteOption.PermanentDelete);
            }
            var temp = (_timetableDataSource._allGroups_Design[1] as TKBDataGroup).Items.Last();
            (_timetableDataSource._allGroups_Design[1] as TKBDataGroup).Items.Clear();
            (_timetableDataSource._allGroups_Design[1] as TKBDataGroup).Items.Add(temp);
        }

        public static void LoadTKBData() {

            _timetableDataSource._allGroups_Design.Clear();

            TKBDataGroup tkb = new TKBDataGroup("TKB", "on cloud", "daa.uit.edu.vn", String.Empty);
            tkb.PopularizeContent(0);

            _timetableDataSource._allGroups_Design.Add(tkb);

            TKBDataGroup tkb_saved = new TKBDataGroup("TKB_SAVED", "on computer", "saved on local catched", String.Empty);
            tkb_saved.PopularizeContent(1);

            _timetableDataSource._allGroups_Design.Add(tkb_saved);

        }

        private static void CreateTimetableGroup(JsonArray array, ObservableCollection<CommonDataGroup> destGroupsList) {

            var group = new TimetableDataGroup("TKB_CHUNG" + Guid.NewGuid().ToString(), String.Empty, DateTime.Now, DateTime.Now);

            // Get data of TimetableDataModel
            var timetable = array.GetObjectAt(0);

            foreach (var key in timetable.Keys) {

                IJsonValue val;

                var provider = CultureInfo.InvariantCulture;
                var format = "d/M/yyyy";

                if (!timetable.TryGetValue(key, out val))
                    continue;

                switch (key) {
                    case "tenthoikhoabieu":
                        group.Ten = group.Title = val.GetString();
                        group.ShortTitle = "Thời khóa biểu lý thuyết";
                        break;
                    case "batdau":
                        group.BatDau = DateTime.ParseExact(val.GetString(), format, provider);
                        break;
                    case "ketthuc":
                        group.KetThuc = DateTime.ParseExact(val.GetString(), format, provider);
                        break;
                    case "danhsachmonhoc":
                        var monhoc = val.GetArray();
                        format = "h:m tt";
                        foreach (var item in monhoc) {
                            var monhocitem = new TimetableSubjectDataItem(String.Empty, String.Empty, String.Empty, String.Empty, 0, String.Empty, String.Empty, 0, DateTime.Now, DateTime.Now, String.Empty);
                            var obj = item.GetObject();
                            foreach (var k in obj.Keys) {
                                IJsonValue val1;
                                if (!obj.TryGetValue(k, out val1))
                                    continue;
                                switch (k) {
                                    case "mamon":
                                        monhocitem.MaMon = val1.GetString();
                                        break;
                                    case "malop":
                                        monhocitem.MaLop = val1.GetString();
                                        break;
                                    case "ten":
                                        monhocitem.Ten = monhocitem.ShortTitle = val1.GetString();
                                        break;
                                    case "sotinchi":
                                        monhocitem.SoTinChi = (int)val1.GetNumber();
                                        break;
                                    case "giangvien":
                                        monhocitem.GiangVien = val1.GetString();
                                        break;
                                    case "phong":
                                        monhocitem.Phong = val1.GetString();
                                        break;
                                    case "ngayhoc":
                                        monhocitem.NgayHoc = (int)val1.GetNumber();
                                        break;
                                    case "batdau":
                                        monhocitem.BatDau = DateTime.ParseExact(val1.GetString(), format, provider);
                                        break;
                                    case "ketthuc":
                                        monhocitem.KetThuc = DateTime.ParseExact(val1.GetString(), format, provider);
                                        break;
                                    case "ghichu":
                                        monhocitem.GhiChu = val1.GetString();
                                        break;
                                }
                            }
                            monhocitem.MaMonHoc = monhocitem.Title = monhocitem.MaMon + "." + monhocitem.MaLop;
                            monhocitem.UniqueId = monhocitem.MaMonHoc + group.MaTKB;
                            monhocitem.Group = group;

                            group.Items.Add(monhocitem);
                        }
                        break;
                }

            }
            group.UniqueId = group.MaTKB;
            //_timetableDataSource._allGroups.Add(group);
            destGroupsList.Add(group);

        }

        private static void CreateCalendarGroup(JsonArray array, ObservableCollection<CommonDataGroup> destGroupsList) {

            var group = new CalendarDataGroup("TKB_SINHVIEN", String.Empty, 0, String.Empty, String.Empty);

            // Get data of TimetableDataModel
            var calendar = array.GetObjectAt(0);

            foreach (var key in calendar.Keys) {

                IJsonValue val;

                var provider = CultureInfo.InvariantCulture;
                var format1 = "d/M/yyyy";
                var format2 = "h:m tt";
                var format3 = "d/M/yyyy h:m tt";

                if (!calendar.TryGetValue(key, out val))
                    continue;

                switch (key) {
                    case "tenlich":
                        group.Ten = group.Title = val.GetString();
                        group.ShortTitle = "Thời khóa biểu sinh viên";
                        break;
                    case "hocky":
                        group.HocKy = (int)val.GetNumber();
                        break;
                    case "namhoc":
                        group.NamHoc = val.GetString();
                        break;
                    case "ghichu":
                        group.GhiChu = val.GetString();
                        break;
                    case "danhsachmonhoc":
                        var monhoc = val.GetArray();
                        foreach (var item in monhoc) {
                            var monhocitem = new CalendarSubjectDataItem(String.Empty, String.Empty, String.Empty, String.Empty, 0, String.Empty, String.Empty, 0, DateTime.Now, DateTime.Now, String.Empty);
                            var obj = item.GetObject();
                            foreach (var k in obj.Keys) {
                                IJsonValue val1;
                                if (!obj.TryGetValue(k, out val1))
                                    continue;
                                switch (k) {
                                    case "mamon":
                                        monhocitem.MaMon = val1.GetString();
                                        break;
                                    case "malop":
                                        monhocitem.MaLop = val1.GetString();
                                        break;
                                    case "ten":
                                        monhocitem.Ten = monhocitem.ShortTitle = val1.GetString();
                                        break;
                                    case "sotinchi":
                                        monhocitem.SoTinChi = (int)val1.GetNumber();
                                        break;
                                    case "giangvien":
                                        monhocitem.GiangVien = val1.GetString();
                                        break;
                                    case "phong":
                                        monhocitem.Phong = val1.GetString();
                                        break;
                                    case "ngayhoc":
                                        monhocitem.NgayHoc = (int)val1.GetNumber();
                                        break;
                                    case "batdau":
                                        monhocitem.BatDau = DateTime.ParseExact(val1.GetString(), format2, provider);
                                        break;
                                    case "ketthuc":
                                        monhocitem.KetThuc = DateTime.ParseExact(val1.GetString(), format2, provider);
                                        break;
                                    case "ghichu":
                                        monhocitem.GhiChu = val1.GetString();
                                        break;
                                    case "thicu":
                                        var thi = val1.GetArray();
                                        foreach (var t in thi) {
                                            var thiobj = new CalendarThiDataItem(String.Empty, DateTime.Now, String.Empty);
                                            var tt = t.GetObject();
                                            foreach (var tk in tt.Keys) {
                                                IJsonValue val2;
                                                if (!obj.TryGetValue(tk, out val2))
                                                    continue;
                                                switch (tk) {
                                                    case "ten":
                                                        thiobj.Ten = val2.GetString();
                                                        break;
                                                    case "ngaygio":
                                                        thiobj.NgayGio = DateTime.ParseExact(val2.GetString(), format3, provider);
                                                        break;
                                                    case "ghichu":
                                                        thiobj.GhiChu = val2.GetString();
                                                        break;
                                                }
                                            }
                                            monhocitem.AllThi.Add(thiobj);
                                        }
                                        break;
                                    case "baitap":
                                        var baitap = val1.GetArray();
                                        foreach (var bt in baitap) {
                                            var baitapobj = new CalendarBaiTapDataItem(String.Empty, DateTime.Now, String.Empty);
                                            var btt = bt.GetObject();
                                            foreach (var btk in btt.Keys) {
                                                IJsonValue val3;
                                                if (!obj.TryGetValue(btk, out val3))
                                                    continue;
                                                switch (btk) {
                                                    case "ten":
                                                        baitapobj.Ten = val3.GetString();
                                                        break;
                                                    case "ngayhethan":
                                                        baitapobj.NgayHetHan = DateTime.ParseExact(val3.GetString(), format1, provider);
                                                        break;
                                                    case "noidung":
                                                        baitapobj.NoiDung = val3.GetString();
                                                        break;
                                                }
                                            }
                                            monhocitem.AllBaiTap.Add(baitapobj);
                                        }
                                        break;
                                }
                            }
                            monhocitem.MaMonHoc = monhocitem.Title = monhocitem.MaMon + "." + monhocitem.MaLop;
                            monhocitem.UniqueId = monhocitem.MaMonHoc + group.MaLich;
                            monhocitem.Group = group;

                            group.Items.Add(monhocitem);
                        }
                        break;
                }
            }
            group.UniqueId = group.MaLich;
            //_timetableDataSource._allGroups.Add(group);
            destGroupsList.Add(group);
        }

        private static void CreateStudentDataItem(JsonArray array) {
            // Get data of TimetableDataModel
            var sv = array.GetObjectAt(0);

            foreach (var key in sv.Keys) {

                IJsonValue val;

                if (!sv.TryGetValue(key, out val))
                    continue;

                switch (key) {
                    case "hoten":
                        _timetableDataSource._studentItem.Ten = val.GetString();
                        break;
                    case "mssv":
                        _timetableDataSource._studentItem.MSSV = val.GetString();
                        break;
                    case "lop":
                        _timetableDataSource._studentItem.Lop = val.GetString();
                        break;
                    case "khoa":
                        _timetableDataSource._studentItem.Khoa = val.GetString();
                        break;
                    case "hocky":
                        _timetableDataSource._studentItem.HocKy = val.GetString();
                        break;
                    case "namhoc":
                        _timetableDataSource._studentItem.NamHoc = val.GetString();
                        break;
                }
                _timetableDataSource._studentItem.Title = _timetableDataSource._studentItem.Ten;
                _timetableDataSource._studentItem.UniqueId = "SINHVIEN";
                _timetableDataSource._studentItem.ShortTitle = _timetableDataSource._studentItem.MSSV;
            }
        }

        private static void CreateTKBGroup(JsonArray array) {

            var destGroupsList = (_timetableDataSource._allGroups_Design.Where(t => t.UniqueId.Equals("TKB")).ElementAt(0) as TKBDataGroup).Items;

            foreach (var ttitem in array) {

                var timetable = ttitem.GetObject();

                var group = new TimetableDataGroup("TKB_CHUNG" + Guid.NewGuid().ToString(), String.Empty, DateTime.Now, DateTime.Now);

                var str = _tempString.Last().Value;
                _tempString.Remove("0");
                _tempString.Add(group.MaTKB, str);

                foreach (var key in timetable.Keys) {

                    IJsonValue val;

                    var provider = CultureInfo.InvariantCulture;
                    var format = "d/M/yyyy";

                    if (!timetable.TryGetValue(key, out val))
                        continue;

                    switch (key) {
                        case "tenthoikhoabieu":
                            group.Ten = group.Title = val.GetString();
                            group.ShortTitle = "on cloud";
                            break;
                        case "batdau":
                            group.BatDau = DateTime.ParseExact(val.GetString(), format, provider);
                            break;
                        case "ketthuc":
                            group.KetThuc = DateTime.ParseExact(val.GetString(), format, provider);
                            break;
                        case "danhsachmonhoc":
                            var monhoc = val.GetArray();
                            format = "h:m tt";
                            foreach (var item in monhoc) {
                                var monhocitem = new TimetableSubjectDataItem(String.Empty, String.Empty, String.Empty, String.Empty, 0, String.Empty, String.Empty, 0, DateTime.Now, DateTime.Now, String.Empty);
                                var obj = item.GetObject();
                                foreach (var k in obj.Keys) {
                                    IJsonValue val1;
                                    if (!obj.TryGetValue(k, out val1))
                                        continue;
                                    switch (k) {
                                        case "mamon":
                                            monhocitem.MaMon = val1.GetString();
                                            break;
                                        case "malop":
                                            monhocitem.MaLop = val1.GetString();
                                            break;
                                        case "ten":
                                            monhocitem.Ten = monhocitem.ShortTitle = val1.GetString();
                                            break;
                                        case "sotinchi":
                                            monhocitem.SoTinChi = (int)val1.GetNumber();
                                            break;
                                        case "giangvien":
                                            monhocitem.GiangVien = val1.GetString();
                                            break;
                                        case "phong":
                                            monhocitem.Phong = val1.GetString();
                                            break;
                                        case "ngayhoc":
                                            monhocitem.NgayHoc = (int)val1.GetNumber();
                                            break;
                                        case "batdau":
                                            monhocitem.BatDau = DateTime.ParseExact(val1.GetString(), format, provider);
                                            break;
                                        case "ketthuc":
                                            monhocitem.KetThuc = DateTime.ParseExact(val1.GetString(), format, provider);
                                            break;
                                        case "ghichu":
                                            monhocitem.GhiChu = val1.GetString();
                                            break;
                                    }
                                }
                                monhocitem.MaMonHoc = monhocitem.Title = monhocitem.MaMon + "." + monhocitem.MaLop;
                                monhocitem.UniqueId = monhocitem.MaMonHoc + "_" + group.MaTKB;
                                monhocitem.Group = group;
                                monhocitem.Icon = "\uE1D3";
                                monhocitem.SetImage("ms-appx:///Assets//uit.png");

                                //Tong hop thong tin mon hoc
                                monhocitem.TongHop = ThuTrongTuan(monhocitem.NgayHoc) + "\n" + "Room: " + monhocitem.Phong + "\n" + "Time: " + monhocitem.BatDau.ToString("hh:mm tt") + " - " + monhocitem.KetThuc.ToString("hh:mm tt");

                                group.Items.Add(monhocitem);
                            }
                            break;
                    }

                }
                group.UniqueId = group.MaTKB;
                group.Icon = "\uE1DB";
                group.SetImage("ms-appx:///Assets//uit.png");
                //_timetableDataSource._allGroups.Add(group);
                destGroupsList.Insert(0, group);

            }

        }

        public static String ThuTrongTuan(int i) {
            switch (i) {
                case 1:
                    return "Sunday";
                case 2:
                    return "Monday";
                case 3:
                    return "Tuesday";
                case 4:
                    return "Wednesday";
                case 5:
                    return "Thursday";
                case 6:
                    return "Friday";
                case 7:
                    return "Saturday";
                default:
                    return String.Empty;
            }
        }

        public static void AddSettingsCommands(SettingsPaneCommandsRequestedEventArgs args) {
            args.Request.ApplicationCommands.Clear();

            SettingsCommand privacyPref = new SettingsCommand("privacyPref", "Privacy Policy", async (uiCommand) => {

                await Windows.System.Launcher.LaunchUriAsync(new Uri("https://www.facebook.com/notes/kha-b%C3%A9o-nguy%E1%BB%85n/privacy-policy/149808155185059"));

            });

            args.Request.ApplicationCommands.Add(privacyPref);

        }

    }

}
